#include "stdafx.h"
#include "NativeScene.h"

#include <QtWidgets/QGraphicsSceneMouseEvent>

#include <metaioSDK/GestureHandler.h>

#include "insNetwork/iInsTcpClient.h"
#include "insApi.h"
#include "AppConfig.h"

NativeScene::NativeScene(QObject *parent) :
	SceneBase(parent)
{
	/*m_earth = 0;
	m_earthOcclusion = 0;
	m_earthIndicators = 0;
	m_earthOpened = false;*/

	if (InitInsNetwork())
	{
		TcpClient = IInsTcpClient::CreateIns();
		if (!TcpClient || !TcpClient->Open(&result))
		{
			qCritical("Create local TCP client failed.");
			return;
		}

		if (!TcpClient->Connect(AppConfig::instance()->ip.c_str(), AppConfig::instance()->port))
		{
			qCritical("CANNOT connect to Unreal Editor.");
			return;
		}
	}
	else {
		qCritical("Failed to initialize network.");
	}
}


NativeScene::~NativeScene()
{
	UninitInsNetwork();
}


void NativeScene::loadContent()
{
	// TODO: Load your own content here

	/*if (!m_pMetaioSDK->setTrackingConfiguration(metaio::Path::fromUTF8("../../../../../templatesContent_crossplatform/TrackingData_MarkerlessFast.xml")))
		qCritical("Failed to load tracking configuration");
	
	const float scale = 11.f;
	const metaio::Rotation rotation = metaio::Rotation(metaio::Vector3d(static_cast<float>(M_PI/2.0), 0.f, 0.f));

	m_earth = m_pMetaioSDK->createGeometry(metaio::Path::fromUTF8("../../../../../templatesContent_crossplatform/Earth.zip"));
	if (m_earth)
	{
		m_earth->setScale(scale);
		m_earth->setRotation(rotation);
	}
	else
		qCritical("Failed to load earth model file");

	m_earthOcclusion = m_pMetaioSDK->createGeometry(metaio::Path::fromUTF8("../../../../../templatesContent_crossplatform/Earth_Occlusion.zip"));
	if (m_earthOcclusion)
	{
		m_earthOcclusion->setScale(scale);
		m_earthOcclusion->setRotation(rotation);
		m_earthOcclusion->setOcclusionMode(true);
	}
	else
		qCritical("Failed to load earth occlusion model file");

	m_earthIndicators = m_pMetaioSDK->createGeometry(metaio::Path::fromUTF8("../../../../../templatesContent_crossplatform/EarthIndicators.zip"));
	if (m_earthIndicators)
	{
		m_earthIndicators->setScale(scale);
		m_earthIndicators->setRotation(rotation);
	}
	else
		qCritical("Failed to load earth indicators model file");*/

	if (!m_pMetaioSDK->setTrackingConfiguration(metaio::Path::fromFSEncoding(AssetPath(TrackingData_PictureMarker.xml))))
		qCritical("Failed to load tracking configuration");

	/*metaio::IGeometry* geometry = m_pMetaioSDK->createGeometry(metaio::Path::fromFSEncoding("../../../../../templatesContent_crossplatform/fish.md2"));
	if (geometry)
		geometry->setScale(10.f);
	else
		qCritical("Failed to load MD2 model file");*/
}


void NativeScene::performRendering()
{
	m_pMetaioSDK->render();
}

void NativeScene::mousePressEvent(QGraphicsSceneMouseEvent* mouseEvent)
{
	super::mousePressEvent(mouseEvent);

	const int x = mouseEvent->scenePos().x();
	const int y = mouseEvent->scenePos().y();

	// Forward event to gesture handler
	if (m_pGestureHandler)
		m_pGestureHandler->touchesBegan(x, y);

	/*metaio::IGeometry* geometry = m_pMetaioSDK->getGeometryFromViewportCoordinates(x, y);

	if (geometry != NULL)
	{
		onGeometryTouched(geometry);
	}*/
}

void NativeScene::mouseMoveEvent(QGraphicsSceneMouseEvent* mouseEvent)
{
	super::mouseMoveEvent(mouseEvent);

	const int x = mouseEvent->scenePos().x();
	const int y = mouseEvent->scenePos().y();

	// Forward event to gesture handler (needed for drag gesture, just like the mouse press/release events)
	if (m_pGestureHandler)
		m_pGestureHandler->touchesMoved(x, y);
}

void NativeScene::mouseReleaseEvent(QGraphicsSceneMouseEvent* mouseEvent)
{
	super::mouseReleaseEvent(mouseEvent);

	// See comment in mouseMoveEvent()
	const int x = mouseEvent->scenePos().x();
	const int y = mouseEvent->scenePos().y();

	// Forward event to gesture handler
	if (m_pGestureHandler)
		m_pGestureHandler->touchesEnded(x, y);
}

void NativeScene::onTrackingEvent(const metaio::stlcompat::Vector< metaio::TrackingValues > &trackingValues)
{
	for (unsigned int i = 0; i < trackingValues.size(); i++)
	{
		const metaio::TrackingValues tv = trackingValues[i];
		if (tv.isTrackingState())
		{
			printf("%s found\n", tv.cosName.c_str());

			char szBuffer[1024];
			sprintf_s(szBuffer, 1024, \
			"{\"Operation\":\"EventTrigger\", \"Name\":\"%s\"}", tv.cosName.c_str());

			/*sprintf_s(szBuffer, 1024, \
				"{\"Operation\":\"SelectActor\", \"ObjectType\":\"%s\", \"Name\":\"%s\"}", \
				"CAMERA", "CameraActor");*/

			std::wstring lwstrData;
			ins::AnsiToUnicode16(szBuffer, lwstrData);
			int iDataLen = ins::UnicodeToUTF8(lwstrData.c_str(), szBuffer, 1024);
			if (!TcpClient->SendData(szBuffer, iDataLen))
			{
				qCritical("SendData Error!");
				break;
			}
		}
	}
}

//void NativeScene::onGeometryTouched(metaio::IGeometry* geometry)
//{
//	if (geometry != m_earthOcclusion)
//	{
//		if (!m_earthOpened)
//		{
//			m_earth->startAnimation("Open", false);
//			m_earthIndicators->startAnimation("Grow", false);
//			m_earthOpened = true;
//		}
//		else
//		{
//			m_earth->startAnimation("Close", false);
//			m_earthIndicators->startAnimation("Shrink", false);
//			m_earthOpened = false;
//		}
//	}
//}
